#include <fermat/net/iobuffer.h>
#include <fermat/common/types.h>
#include <cerrno>
#include <sys/uio.h>


namespace fermat {
namespace net {
const char IOBuffer::kCRLF[] = "\r\n";

const size_t IOBuffer::kPrepend;
const size_t IOBuffer::kInitSize;

ssize_t IOBuffer::readFd(int fd, int* savedErrno)
{
    char extrabuf[65536];
    struct iovec vec[2];
    const size_t writable = writableBytes();
    vec[0].iov_base = begin()+_writerIndex;
    vec[0].iov_len = writable;
    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof extrabuf;
    const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1;
    const ssize_t n = ::readv(fd, vec, iovcnt);
    if (n < 0) {
        *savedErrno = errno;
    } else if (implicit_cast<size_t>(n) <= writable) {
        _writerIndex += n;
    } else {
        _writerIndex = _buffer.size();
        append(extrabuf, n - writable);
    }
    return n;
}

}

}